package com.zhala.web.config;

import com.sun.jna.Pointer;
import com.zhala.system.domain.ZlHumanNumberStatistic;
import com.zhala.system.service.ZlHumanNumberStatisticService;
import com.zhala.web.ai.lib.NetSDKLib;
import com.zhala.web.ai.lib.Utils;
import com.zhala.web.ai.module.GateModule;
import com.zhala.web.ai.module.LoginModule;
import com.zhala.web.ai.netsdk.common.Res;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import javax.swing.*;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Vector;


@Component
public class GateConfig implements ApplicationListener<ApplicationReadyEvent> {

    private static ZlHumanNumberStatisticService service;
    private static NetSDKLib.LLong userId1;
    private static NetSDKLib.LLong userId2;
    private static JTextField cardNameTextField;
    private static NetSDKLib.LLong m_hAttachHandle2;
    private static NetSDKLib.LLong m_hAttachHandle1;


    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        System.out.print("门禁监测");
        service = event.getApplicationContext().getBean(ZlHumanNumberStatisticService.class);
        start();
    }

    private void start() {
        //LoginModule  初始化，登陆登出相关
        //GateModule   卡片的增删改查相关
        //初始化
        boolean boo = LoginModule.init(disConnect, haveReConnect);
        if (boo) {
            System.out.println("初始化SDK成功");
        }
        //登录
        userId1 = loginResult("192.168.1.151", 37777, "admin", "ggc123456");//todo 改为真实的
        m_hAttachHandle1 = subscribe(userId1, 0);


        userId2 = loginResult("192.168.1.152", 37777, "admin", "ggc123456");//todo 改为真实的
        m_hAttachHandle2 = subscribe(userId2, 0);
    }


    // 设备断线通知回调
    private static DisConnect disConnect = new DisConnect();

    // 网络连接恢复
    private static HaveReConnect haveReConnect = new HaveReConnect();


    /// //////////////面板///////////////////
    // 设备断线回调: 通过 CLIENT_Init 设置该回调函数，当设备出现断线时，SDK会调用该函数
    private static class DisConnect implements NetSDKLib.fDisConnect {
        @Override
        public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
            System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);
            // 断线提示
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Res.string().getGate() + " : " + Res.string().getDisConnectReconnecting());
                }
            });
        }
    }

    // 网络连接恢复，设备重连成功回调
    // 通过 CLIENT_SetAutoReconnect 设置该回调函数，当已断线的设备重连成功时，SDK会调用该函数
    private static class HaveReConnect implements NetSDKLib.fHaveReConnect {
        @Override
        public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
            System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);

            // 重连提示
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Res.string().getGate() + " : " + Res.string().getOnline());
                }
            });
        }
    }


    // 登录
    private Vector<String> chnList = new Vector<>();

    public NetSDKLib.LLong loginResult(String ip, Integer port, String suer, String pwd) {
        NetSDKLib.LLong m_hLoginHandle = LoginModule.login2(ip, port, suer, pwd);
        if (m_hLoginHandle.longValue() != 0) {
            for (int i = 1; i < LoginModule.m_stDeviceInfo.byChanNum + 1; i++) {
                chnList.add(Res.string().getChannel() + " " + String.valueOf(i));
            }
            System.out.println("登陆成功," + chnList.toString());
            return m_hLoginHandle;
        } else {
            System.out.println("登陆失败");
            throw new RuntimeException("登录异常");
        }
    }

    //订阅
    public static NetSDKLib.LLong m_hAttachHandle = new NetSDKLib.LLong(0);

    public NetSDKLib.LLong subscribe(NetSDKLib.LLong userId, int channelId) {
        m_hAttachHandle = GateModule.realLoadPic(userId, channelId, AnalyzerDataCB.getInstance());
        if (m_hAttachHandle.longValue() != 0) {
            System.out.println("订阅成功");
        } else {
            System.out.println("订阅失败");
        }
        return m_hAttachHandle;
    }


    //订阅后事件回调
    private static class AnalyzerDataCB implements NetSDKLib.fAnalyzerDataCallBack {

        private static AnalyzerDataCB INSTANCE;
        private NetSDKLib.LLong userId;

        private AnalyzerDataCB() {

        }

        public static AnalyzerDataCB getInstance() {
            if (INSTANCE == null) {
                INSTANCE = new AnalyzerDataCB();
            }
            return INSTANCE;
        }


        @Override
        public int invoke(NetSDKLib.LLong lAnalyzerHandle, int dwAlarmType,
                          Pointer pAlarmInfo, Pointer pBuffer, int dwBufSize,
                          Pointer dwUser, int nSequence, Pointer reserved) throws UnsupportedEncodingException {
            if (lAnalyzerHandle.longValue() == 0 || pAlarmInfo == null) {
                return -1;
            }
            NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO msg = new NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO();
            Charset encode = Charset.forName(Utils.getPlatformEncode());

            ///< 门禁事件
            if (dwAlarmType == NetSDKLib.EVENT_IVS_ACCESS_CTL) {
                //todo 这里是将收订的订阅数据 保存到数据库
                ZlHumanNumberStatistic zlHumanNumberStatistic = new ZlHumanNumberStatistic();
                String szname;
                if (msg.szName == null || msg.szName.length == 0) {
                    szname = "";
                } else {
                    szname = new String(msg.szName, encode).trim();
                }
                zlHumanNumberStatistic.setNikename(szname);
                zlHumanNumberStatistic.setDays(new Date());
                LocalDateTime now = LocalDateTime.now();
                int hour = now.getHour();
                zlHumanNumberStatistic.setHours(hour);
                if (lAnalyzerHandle.longValue() == m_hAttachHandle2.longValue()){
                    zlHumanNumberStatistic.setStatus(2);
                }else {
                    zlHumanNumberStatistic.setStatus(1);
                }
                int i = service.save(zlHumanNumberStatistic);
            }
            return 0;
        }
    }


    // 取消订阅
    private void cancelSubscribe() {
        GateModule.stopRealLoadPic(m_hAttachHandle);
    }


}

